/**
 * Gitee API 帮助类
 * 提供与 Gitee API v5 交互的常用方法
 */
class GiteeApiHelper {
  /**
   * 构造函数
   * @param {string} accessToken - Gitee 访问令牌
   */
  constructor(accessToken) {
    this.baseUrl = 'https://gitee.com/api/v5';
    this.accessToken = accessToken;
    this.headers = {
      'Content-Type': 'application/json',
      'Authorization': `token ${this.accessToken}`
    };
  }

  /**
   * 设置访问令牌
   * @param {string} accessToken - 新的访问令牌
   */
  setAccessToken(accessToken) {
    this.accessToken = accessToken;
    this.headers.Authorization = `token ${this.accessToken}`;
  }

  /**
   * 通用请求方法
   * @param {string} endpoint - API 端点
   * @param {string} method - 请求方法 (GET, POST, PUT, DELETE 等)
   * @param {Object} data - 请求数据
   * @returns {Promise} - 返回请求结果的 Promise
   */
  async request(endpoint, method = 'GET', data = {}) {
    try {
      let url = `${this.baseUrl}${endpoint}`;
      const options = {
        method,
        headers: this.headers
      };

      if (method !== 'GET') {
        options.body = JSON.stringify(data);
      } else if (Object.keys(data).length > 0) {
        // 为 GET 请求添加查询参数
        const queryParams = new URLSearchParams(data);
        url += `?${queryParams}`;
      }

      const response = await fetch(url, options);

      if (!response.ok) {
        throw new Error(`API 请求失败: ${response.status} ${response.statusText}`);
      }

      return await response.json();
    } catch (error) {
      console.error('Gitee API 请求错误:', error);
      throw error;
    }
  }

  // ------------------- 动态通知相关方法 -------------------

  /**
   * 列出 watch 了仓库的用户
   * @param {string} owner - 仓库所有者
   * @param {string} repo - 仓库名称
   * @param {Object} params - 可选参数
   * @returns {Promise} - 返回用户列表的 Promise
   */
  async getRepoWatchers(owner, repo, params = {}) {
    return this.request(`/repos/${owner}/${repo}/subscribers`, 'GET', params);
  }

  /**
   * 列出仓库的所有动态
   * @param {string} owner - 仓库所有者
   * @param {string} repo - 仓库名称
   * @param {Object} params - 可选参数
   * @returns {Promise} - 返回动态列表的 Promise
   */
  async getRepoActivities(owner, repo, params = {}) {
    return this.request(`/repos/${owner}/${repo}/events`, 'GET', params);
  }

  /**
   * 列出一个仓库里的通知
   * @param {string} owner - 仓库所有者
   * @param {string} repo - 仓库名称
   * @param {Object} params - 可选参数
   * @returns {Promise} - 返回通知列表的 Promise
   */
  async getRepoNotifications(owner, repo, params = {}) {
    return this.request(`/repos/${owner}/${repo}/notifications`, 'GET', params);
  }

  /**
   * 标记一个仓库里的通知为已读
   * @param {string} owner - 仓库所有者
   * @param {string} repo - 仓库名称
   * @returns {Promise} - 返回操作结果的 Promise
   */
  async markRepoNotificationsAsRead(owner, repo) {
    return this.request(`/repos/${owner}/${repo}/notifications`, 'PUT');
  }

  /**
   * watch 一个仓库
   * @param {string} owner - 仓库所有者
   * @param {string} repo - 仓库名称
   * @returns {Promise} - 返回操作结果的 Promise
   */
  async watchRepo(owner, repo) {
    return this.request(`/user/subscriptions/${owner}/${repo}`, 'PUT');
  }

  /**
   * 取消 watch 一个仓库
   * @param {string} owner - 仓库所有者
   * @param {string} repo - 仓库名称
   * @returns {Promise} - 返回操作结果的 Promise
   */
  async unwatchRepo(owner, repo) {
    return this.request(`/user/subscriptions/${owner}/${repo}`, 'DELETE');
  }

  /**
   * 检查授权用户是否 watch 了一个仓库
   * @param {string} owner - 仓库所有者
   * @param {string} repo - 仓库名称
   * @returns {Promise} - 返回检查结果的 Promise
   */
  async checkIfWatched(owner, repo) {
    try {
      const response = await this.request(`/user/subscriptions/${owner}/${repo}`, 'GET');
      return response !== undefined;
    } catch (error) {
      if (error.message.includes('404')) {
        return false;
      }
      throw error;
    }
  }

  // ------------------- 仓库相关方法 -------------------

  /**
   * 获取仓库详情
   * @param {string} owner - 仓库所有者
   * @param {string} repo - 仓库名称
   * @returns {Promise} - 返回仓库详情的 Promise
   */
  async getRepoDetails(owner, repo) {
    return this.request(`/repos/${owner}/${repo}`, 'GET');
  }

  /**
   * 获取文件内容
   * @param {string} owner - 仓库所有者
   * @param {string} repo - 仓库名称
   * @param {string} path - 文件路径
   * @param {string} ref - 分支或提交哈希
   * @returns {Promise} - 返回文件内容的 Promise
   */
  async getFileContent(owner, repo, path, ref = 'master') {
    return this.request(`/repos/${owner}/${repo}/contents/${path}`, 'GET', { ref });
  }

  /**
   * 创建或更新文件
   * @param {string} owner - 仓库所有者
   * @param {string} repo - 仓库名称
   * @param {string} path - 文件路径
   * @param {string} content - 文件内容 (Base64 编码)
   * @param {string} message - 提交信息
   * @param {string} branch - 分支
   * @returns {Promise} - 返回操作结果的 Promise
   */
  async createOrUpdateFile(owner, repo, path, content, message, branch = 'master') {
    return this.request(`/repos/${owner}/${repo}/contents/${path}`, 'PUT', {
      content,
      message,
      branch
    });
  }

  /**
   * 删除文件
   * @param {string} owner - 仓库所有者
   * @param {string} repo - 仓库名称
   * @param {string} path - 文件路径
   * @param {string} message - 提交信息
   * @param {string} branch - 分支
   * @returns {Promise} - 返回操作结果的 Promise
   */
  async deleteFile(owner, repo, path, message, branch = 'master') {
    // 先获取文件的 SHA
    const fileInfo = await this.getFileContent(owner, repo, path, branch);
    return this.request(`/repos/${owner}/${repo}/contents/${path}`, 'DELETE', {
      message,
      sha: fileInfo.sha,
      branch
    });
  }
}

export default GiteeApiHelper;